/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package controller;

import java.awt.Point;
import java.awt.PopupMenu;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.JTree;
import model.treeModel;
import store.treeStore;
import view.treeView;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
import model.hitoModel;
import type.hitoType;
import type.mouseType;

/**
 *
 * @author JorgeLuis
 */
public class treeController {
    
    private mainController                  mainController;
    private treeView                        view                = new treeView();
    private treeStore                       trees               = new treeStore();
    private DefaultMutableTreeNode          tree;
    private TreePath                        nodeSelect;
    
    private String                          textDeleteFloor     = "Delete Floor";
    private String                          textEditFloor       = "Edit Floor";
    private String                          textAddFloor        = "Add Floor";
    
    private String                          textDeleteEdifice   = "Delete Edifice";
    private String                          textEditEdifice     = "Edit Edifice";
    
    private String                          textDeleteSite      = "Delete Site";
    private String                          textEditSite        = "Edit Site";    
    
    private int                             numberFloor         = 1;
    

    public treeController() {
        this.view.controller(this);
    }     
    
    public void mainController(mainController aThis) {
        this.mainController = aThis;
        
    }
    
    public treeView getView(){
        return this.view;
    }

    /*
      inicia el arbol con algun nombre, el nombre por si es el nombre del proyecto
    */ 
    public void startTree(String name, int hashCode) {
               
        this.tree           = new DefaultMutableTreeNode(name);
        treeModel node      = new treeModel(hashCode, -1, tree.hashCode(), name, hitoType.CAMPUS, tree);
        
                
        trees.add(node);
        
        this.view.setModel(new DefaultTreeModel(this.tree));
        this.view.setSize(200, 200);
    }
   
    public void setNameParent(String name){
        this.tree.setUserObject(name);
    }
    
    /*
        Agrega un nodo al arbol y agrega una capa al store de layer
    */
    public void addFloor(int parentId){
     
        // busca el padre para asignar el nodo

        DefaultMutableTreeNode parent = trees.findNode(parentId);

        if(parent == null){
            System.out.println("No se encontro padre");
            return;
        }

        // crea el nodo (floor)
        DefaultMutableTreeNode floor = new DefaultMutableTreeNode("floor "+this.numberFloor);
        this.numberFloor += 1;
        
        int id = this.mainController.newLayer(parentId);

        treeModel node = new treeModel(id, parentId, floor.hashCode(), textEditSite, hitoType.FLOOR, floor);


        this.trees.add(node);
        parent.add(floor);             
        
        System.out.println("Se creo el Piso "+floor.hashCode());
        
        this.view.repaint();
        this.view.updateUI();
    }
 
    /*
        Agregar un sitio
    */
    public void addSite(int parentId, int id, String name){
     
        // busca el padre para asignar el nodo

        treeModel parent = trees.findIdTree(parentId);

        if(parent == null){
            System.out.println("No se encontro padre");
            return;
        }

        // crea el nodo (site)
        DefaultMutableTreeNode site = new DefaultMutableTreeNode(name);
        
        
        treeModel node = new treeModel(id, parentId, site.hashCode(), name, hitoType.SITE, site);

        this.trees.add(node);
        parent.getNodo().add(site);
        
        this.view.repaint();
        this.view.updateUI();
    }
    
    /*
        Agregar un edificio
    */
    public void addEdifise(int parentid ,int id, String name){
        
//        System.out.println("En la Funcion addEdifise new "+ id);
//        System.out.println("parent Id "+parentid);
        
        // busca el padre para asignar el nodo        
        treeModel parent = this.trees.findIdTree(parentid);

        if(parent == null){
            System.out.println("No se encontro padre");
            return;
        }

        // crea el nodo (site)
        DefaultMutableTreeNode edifice = new DefaultMutableTreeNode(name);


        treeModel node = new treeModel(id, parentid, edifice.hashCode(), name, hitoType.EDIFICE, edifice);
    
        this.trees.add(node);
        parent.getNodo().add(edifice);
        
        this.view.repaint();
        this.view.updateUI();
    }

    public TreePath selectNode(Point point){
        nodeSelect = this.view.getPathForLocation(point.x,point.y);    
        return nodeSelect;
    }

    public void action(mouseController mouse) {
        
        if(mouse.getState() == mouseType.mouseClicked && mouse.isClickLeft()){
            mouse.setClickLeft(false);
            
            selectNode(mouse.getPoint()); 
            
            if(nodeSelect == null){
                System.out.println("No Hubo selection");
                return;
            }
            
            System.out.println("Seleciono el elemento "+nodeSelect.hashCode());

            treeModel element = trees.findNodeTree(nodeSelect.hashCode());
            
            if(element == null){
                System.out.println("No se encontro relacion en el Nodo");
                return;
            }
            System.out.println("Se encontro relacion en el Nodo "+element.getName());
            System.out.println("tipo de elemento "+element.getType().name());
            // Si es un tipo Piso se cambia el layer por el correpondiente
            
            if(element.getType() == hitoType.FLOOR || element.getType() == hitoType.CAMPUS){
                
                this.mainController.changeLayer(element.getId());
            }
        }
        
        else if(mouse.getState() == mouseType.mouseClicked && mouse.isClickRigth()){
            mouse.setClickRigth(false);

            selectNode(mouse.getPoint());            

            if(nodeSelect == null){
                System.out.println("No se seleciono elemento");
                return;
            }
            
            System.out.println("Se seleciono elemento "+nodeSelect.hashCode());

            treeModel element = trees.findNodeTree(nodeSelect.hashCode());
            
            if(element == null){
                System.out.println("No se encontro relacion en el Nodo");
                return;
            }
            
            System.out.println("Se encontro relacion en el Nodo "+element.getName());

            if(element.getType()        ==  hitoType.EDIFICE){
                this.subMenuEdifice(mouse.getPoint());
            }
            else if(element.getType()   ==  hitoType.FLOOR){
                this.subMenuFloor(mouse.getPoint());
            }
            else if(element.getType()   ==  hitoType.SITE){
                this.subMenuSite(mouse.getPoint());
            }


        }
    }
    
    public void subMenuEdifice(Point point){
         
        PopupMenu submenu = new PopupMenu();
         
        submenu.add(    this.textAddFloor   );
        submenu.add(    this.textDeleteEdifice);
        submenu.add(    this.textEditEdifice);
        
        this.view.add(submenu);
        
        submenu.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                actionSelect(ae);
            }
        });
        
        submenu.show(view,point.x ,point.y);
        
        this.view.updateUI();
    }

    private void subMenuSite(Point point) {       
        
        PopupMenu submenu = new PopupMenu();
         
        submenu.add(this.textEditSite);
        submenu.add(this.textDeleteSite);
        
        this.view.add(submenu);
        
        submenu.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                actionSelect(ae);
            }
        });
        submenu.show(view,point.x ,point.y);
        
        this.view.updateUI();
        
    }
    
    /*
        
     */
    private void actionSelect(ActionEvent ae) {
        
        if(this.textAddFloor.equals(ae.getActionCommand())){
            int parent = nodeSelect.hashCode();
            this.addFloor(parent);
        }
        else if(this.textEditEdifice .equals(ae.getActionCommand())){
            
        }
        else if(this.textEditFloor .equals(ae.getActionCommand())){
        
        }
        else if(this.textDeleteEdifice .equals(ae.getActionCommand())){
            int id = nodeSelect.hashCode();
            this.deleteEdifice(id);
        }
        else if(this.textDeleteFloor .equals(ae.getActionCommand())){
            int id = nodeSelect.hashCode();
            this.deleteFloor(id);
        }
    }

    private void subMenuFloor(Point point) {
        
        PopupMenu submenu = new PopupMenu();
         
        
        submenu.add(    this.textDeleteFloor);
        submenu.add(    this.textEditFloor);
        
        this.view.add(submenu);
        
        submenu.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ae) {
                actionSelect(ae);
            }
        });
        
        submenu.show(view,point.x ,point.y);
        
        this.view.updateUI();
    }

    public treeStore getStore() {
        return this.trees;
    }

    /*
        editamos la vista del arbol
    */
    public void editTree(hitoModel hito, int parentId) {
        
        // buscamos en el store de arbol (treeStore) si existe el elmento.
        treeModel nodeTree = this.trees.findIdTree(hito.getId());
        
        // si no se encontro nada se asume que es nuevo y se adiciona
        
        System.out.println("editTree "+nodeTree);
        if(nodeTree == null){
            
            switch(hito.getType()){
                
                case EDIFICE:
                    this.addEdifise(parentId, hito.getId(), hito.getName());
                    break;
                    
                case SITE:
                    this.addSite(parentId, hito.getId(), hito.getName());
                    break;
            }
        }
        // de lo contrario se edita
        else{
            
            if(nodeTree.getName() != hito.getName()){
                nodeTree.setName(hito.getName());
                nodeTree.getNodo().setUserObject(hito.getName());
            }
            
            if(nodeTree.getType() != hito.getType()){
                nodeTree.setType(hito.getType());
            }
                    
        }
        
        this.view.repaint();
        this.view.updateUI();
    }

    private void deleteEdifice(int id) {
        
        treeModel nodeTree = this.trees.findNodeTree(id);
        
        this.mainController.deleteEdifice(nodeTree.getId());
    
    }

    private void deleteFloor(int id) {
        treeModel nodeTree = this.trees.findNodeTree(id);
        
        nodeTree = this.trees.findNodeTree(nodeTree.getIdParent());
        System.out.println("node "+nodeTree);
        nodeTree.getNodo().remove(nodeTree.getNodo());
        
    }

    
}
